package edu.udo.sopra10.chaturaji.gui;

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.Timer;
import javax.swing.border.Border;

import se.datadosen.component.RiverLayout;
import edu.udo.sopra10.chaturaji.controllers.GameController;
import edu.udo.sopra10.chaturaji.gui.util.SimpleGridBagConstraints;

/**
 * OverlayPanel, to be used as a GlassPane, that offers miscellaneous tasks
 * that require user interaction.
 * 
 * @author Patrick Westerhoff
 */
public class OverlayPanel extends JPanel implements ActionListener
{
	private static final long serialVersionUID = -7132617715877489142L;
	private static final int PADDING = 3;
	private static final Border INNER_BORDER = BorderFactory.createEmptyBorder( 10, 10, 10, 10 );
	
	// components
	private JPanel mainPanel;
	private JButton rollButton;
	private JButton okayButton;
	private JTextField emailTextField1 = new JTextField();
	private JTextField emailTextField2 = new JTextField();
	private DicePanel dicePanel;
	
	private Timer hideTimer;
	
	/**
	 * Constructs an OverlayPanel that is hidden by default.
	 * 
	 */
	public OverlayPanel ()
	{
		super( new GridBagLayout() );
		
		/* reuseable components */
		rollButton = new JButton( "Würfeln" );
		rollButton.addActionListener( this );
		
		okayButton = new JButton( "Ok" );
		okayButton.addActionListener( this );
		
		hideTimer = new Timer( 2000, this );
		hideTimer.setRepeats( false );
		hideTimer.addActionListener( this );
		
		dicePanel = new DicePanel();
		dicePanel.addActionListener( this );
		
		/* main panel */
		mainPanel = new JPanel( new RiverLayout( PADDING, PADDING ) );
		mainPanel.setBackground( Color.WHITE );
		
		SimpleGridBagConstraints c = new SimpleGridBagConstraints();
		c.anchor = GridBagConstraints.CENTER;
		
		this.addMouseListener( new MouseAdapter()
			{} );
		this.add( mainPanel, c );
		this.setOpaque( false );
	}
	
	/**
	 * Initializes the overlay display at the beginning of a turn.
	 * 
	 * @param playerStatusPanel referenced {@link PlayerStatusPanel}.
	 */
	private void initializeTurnDisplay ( PlayerStatusPanel playerStatusPanel, String additionalText )
	{
		// set border
		mainPanel.setBorder( BorderFactory.createCompoundBorder( BorderFactory.createMatteBorder( 2, 2, 10, 2,
				playerStatusPanel.getPlayerColor() ), INNER_BORDER ) );
		
		// construct text
		StringBuilder player = new StringBuilder( playerStatusPanel.getPlayerName() );
		
		if ( !playerStatusPanel.getPlayerType().equals( "" ) )
		{
			player.append( " (" );
			player.append( playerStatusPanel.getPlayerType() );
			player.append( ")" );
		}
		player.append( " ist am Zug." );
		
		// append additional text
		if ( additionalText != null && additionalText.equals( "" ) )
		{
			player.append( " " );
			player.append( additionalText );
		}
		
		// display
		mainPanel.removeAll();
		mainPanel.add( "", new JLabel( player.toString() ) );
		mainPanel.add( "p center", dicePanel );
	}
	
	/**
	 * Shows the roll animation.
	 * 
	 * @param d1 side of first die.
	 * @param d2 side of second die.
	 */
	public void rollTo ( byte d1, byte d2 )
	{
		dicePanel.rollTo( d1, d2 );
	}
	
	/**
	 * Shows the overlay with a prompt asking the human player to roll the
	 * dice.
	 * 
	 * @param playerStatusPanel referenced {@link PlayerStatusPanel}.
	 */
	public void showHumanTurnOverlay ( PlayerStatusPanel playerStatusPanel )
	{
		initializeTurnDisplay( playerStatusPanel, "Bitte würfeln." );
		
		mainPanel.add( "p center", rollButton );
		
		this.setVisible( true );
	}
	
	/**
	 * Shows the overlay with a information about the AI turn while animating
	 * the dice roll.
	 * 
	 * @param playerStatusPanel referenced {@link PlayerStatusPanel}.
	 */
	public void showAITurnOverlay ( PlayerStatusPanel playerStatusPanel )
	{
		initializeTurnDisplay( playerStatusPanel, null );
		this.setVisible( true );
	}
	
	
	/**
	 * Shows the overlay with a prompt asking the game operator to enter the
	 * received turn data of the email player.
	 * 
	 * @param playerStatusPanel referenced {@link PlayerStatusPanel}.
	 */
	public void showEmailTurnOverlay ( PlayerStatusPanel playerStatusPanel )
	{
		initializeTurnDisplay( playerStatusPanel, "Bitte E-Mail Daten eingeben." );
		
		emailTextField1.setText( "" );
		emailTextField2.setText( "" );
		mainPanel.add( "p", emailTextField1 );
		mainPanel.add( "p", emailTextField2 );
		mainPanel.add( "p center", okayButton );
		this.setVisible( true );
	}
	
	/**
	 * Hides the overlay after a delay.
	 * 
	 */
	public void hideOverlay ()
	{
		if ( !hideTimer.isRunning() )
			hideTimer.start();
	}
	
	@Override
	public void actionPerformed ( ActionEvent event )
	{
		if ( event.getSource().equals( hideTimer ) )
		{
			GamePanel.guiLock.unlock();
			this.setVisible( false );
			rollButton.setEnabled( true );
		}
		else if ( event.getSource().equals( dicePanel ) )
		{
			hideOverlay();
		}
		else if ( event.getSource().equals( rollButton ) )
		{
			rollButton.setEnabled( false );
			GameController.roll();
		}
		else if ( event.getSource().equals( okayButton ) )
		{
			hideOverlay();
		}
	}
}